/**@file    sys_posix.h
 * @note  
 * @brief  
 * @author 
 */

#if !defined(_SYS_POSIX_H_) && !defined(_MSC_VER)
#define _SYS_POSIX_H_

#ifndef CONFIG_RTOS

#include <pthread.h>
#include <mqueue.h>
#include <semaphore.h>
#else
#include "AmbaKAL.h"
#endif
#include "app_common.h"

__BEGIN_DECLS;

#ifndef CONFIG_RTOS
/*posix接口api重定义*/
typedef mqd_t MSG_Q_ID;
typedef sem_t SEM_ID;
typedef pthread_t TASK_ID;
typedef pthread_mutex_t MUTEX_ID;
#else
/*posix接口api重定义*/
typedef struct _AMBA_MSG_Q_t_
{
    AMBA_KAL_MSG_QUEUE_t MsgQueue;
    UINT8 *MsgQueBuf;
} AMBA_MSG_Q_t;

typedef AMBA_MSG_Q_t MSG_Q_ID;
typedef AMBA_KAL_SEM_t SEM_ID;
typedef AMBA_KAL_TASK_t TASK_ID;
typedef AMBA_KAL_MUTEX_t MUTEX_ID;
#endif

#ifndef CONFIG_RTOS
/* TASK_PRIORITY_0最高优先级 */
#define TASK_PRIORITY_0 99 /*highest*/
#define TASK_PRIORITY_1 90
#define TASK_PRIORITY_2 80
#define TASK_PRIORITY_3 70
#define TASK_PRIORITY_4 60
#define TASK_PRIORITY_5 50 /*lowest*/

#define MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP
#define MUTEX_RELOCK PTHREAD_MUTEX_RECURSIVE_NP
#else
/* TASK_PRIORITY_0最高优先级 */
#define TASK_PRIORITY_0 70
#define TASK_PRIORITY_1 80
#define TASK_PRIORITY_2 90
#define TASK_PRIORITY_3 100
#define TASK_PRIORITY_4 110
#define TASK_PRIORITY_5 120

#define MUTEX_NORMAL 0
#define MUTEX_RELOCK 0
#endif

/* semaphore options */
#define SEM_EMPTY 0
#define SEM_FULL 1

/* timeout options */
#define NO_WAIT 0
#define WAIT_FOREVER (-1)

//#define  TASK_COMM_LEN      64

typedef void *(*FUNCPTR)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *);

/*
**  pthread function
*/
/**@brief  创建线程
 * @param  pTid      任务ID句柄指针
 * @param  pTaskName 任务名,最大长度16，且必须为静态或全局变量
 * @param  priority  任务优先级
 * @param  stacksize 创建任务栈大小
 * @param  funcptr   创建任务函数
 * @param  args      参数个数
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_pthread_create(TASK_ID *pTid, CHAR *pTaskName, UINT32 priority, UINT32 stacksize,
                          void *(*funcptr)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *),
                          unsigned args, ...);

/**@brief  取消线程
 * @param  uId      任务ID句柄
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_pthread_cancel(TASK_ID *uId);

/**@brief  验证线程是否存在
 * @param  uId     任务ID句柄
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_pthread_verify(TASK_ID *uId);

/**@brief  阻塞线程
 * @param  uId      任务ID句柄
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_pthread_suspend(TASK_ID *uId);

/**@brief  恢复阻塞的线程
 * @param  uId      任务ID句柄
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_pthread_reume(TASK_ID *uId);

/**@brief  创建互斥锁
 * @param  pMux     互斥锁句柄指针
 * @param  iType    互斥锁类型
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mutex_create(MUTEX_ID *pstMutex, INT32 iType);

/**@brief  加锁
 * @param  pMux     互斥锁句柄指针
 * @param  iWaitMs  等待时间
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mutex_lock(MUTEX_ID *pstMutex, INT32 iWaitMs);

/**@brief  解锁
 * @param  pMux     互斥锁句柄指针
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mutex_unlock(MUTEX_ID *pstMutex);

/**@brief  销毁锁句柄
 * @param  pMux     互斥锁句柄指针
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mutex_destroy(MUTEX_ID *pstMutex);

/**@brief  创建一个消息队列
 * @param  pName     消息队列名字
 * @param  iMaxMsg   一个消息队列最大消息个数
 * @param  iMsgLen   消息长度
 * @return 成功返回 消息队列句柄
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mqueue_create(MSG_Q_ID *pstHandle, const CHAR *pName, INT32 iMaxMsg, INT32 iMsgLen);

/**@brief  发送消息
 * @param  mqId     消息队列句柄
 * @param  pMsg     发送的消息
 * @param  uLen     消息长度
 * @param  iWaitMs  阻塞时长
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mqueue_send(MSG_Q_ID *mqId, const CHAR *pMsg, UINT32 uLen, INT32 iWaitMs);

/**@brief  接受消息
 * @param  mqId     消息队列句柄
 * @param  pMsg     接受消息缓存
 * @param  uLen     缓存大小
 * @param  iWaitMs  阻塞时长
 * @return 成功返回 接收的字节数
 * @return 错误返回 ERROR
 * @see
 * @note
 */
UINT32 sys_mqueue_recv(MSG_Q_ID *mqId, CHAR *pMsgBuf, INT32 iBufLen, INT32 iWaitMs);

/**@brief  关闭消息队列
 * @param  mqId     消息队列句柄
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_mqueue_close(MSG_Q_ID *mqId);

/**@brief  创建信号量
 * @param  semId   信号量句柄指针
 * @param  uVal    信号量初始值
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_sem_create(SEM_ID *pstSem, UINT32 uVal);

/**@brief  释放一个信号量资源
 * @param  semId   信号量句柄指针
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_sem_post(SEM_ID *semId);

/**@brief  获取一个信号量资源
 * @param  semId   信号量句柄指针
 * @param  uWaitMs 阻塞时长
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_sem_wait(SEM_ID *pstSem, UINT32 uWaitMs);

/**@brief  销毁信号量
 * @param  semId   信号量句柄指针
 * @return 成功返回 0
 * @return 错误返回 其他
 * @see
 * @note
 */
UINT32 sys_sem_destroy(SEM_ID *pstSem);

/**@brief  阻塞线程,毫秒
 * @param  msec   阻塞时长
 * @return 成功返回 0
 * @return 错误返回 -1
 * @see
 * @note
 */
UINT32 sys_wait_msec(UINT32 msec);

#if 1
#define pthreadMutexInit sys_mutex_create
#define pthreadMutexLock sys_mutex_lock
#define pthreadMutexUnlock sys_mutex_unlock
#define pthreadMutexDestroy sys_mutex_destroy
#ifdef CONFIG_SUPPORT_A3N_L
#define pthreadIdVerify sys_pthread_exist
#else
#define pthreadIdVerify sys_pthread_verify
#endif
#define pthreadSpawn(ptid, priority, ...) sys_pthread_create(ptid, NULL, priority, ##__VA_ARGS__)
#define semInit sys_sem_create
#define semWait sys_sem_wait
#define semPost sys_sem_post
#define semDestroy sys_sem_destroy
#endif

__END_DECLS;

#endif
